package com.xiyuan.smartutils.template.engine.expression.operator.logic;

import com.xiyuan.smartutils.Types;

import com.xiyuan.smartutils.template.engine.VariableMap;
import com.xiyuan.smartutils.template.engine.exception.ExpressionException;
import com.xiyuan.smartutils.template.engine.expression.Expression;
import com.xiyuan.smartutils.template.engine.expression.operator.Operator;

/**
 * 逻辑与运算(&&)
 * 
 * @author lgz 2020年12月7日 新建与整理
 */
public class _And extends Operator
{
    private static final long serialVersionUID = 1L;
    private final Expression left;
    private final Expression right;
    
    private boolean isDouble = false;
    
    public _And(String path, int line, int column, Expression left, Expression right)
    {
        super(path, line, column);
        this.left = left;
        this.right = right;
        this.assertSymbo("逻辑 &" + (this.isDouble ? "& " : " "), left, right);
    }
    
    @Override
    public int getType()
    {
        return AND;
    }
    
    public _And setDouble(boolean isDouble)
    {
        this.isDouble = isDouble;
        return this;
    }
    
    @Override
    protected Object build(VariableMap variableMap)
    {
        Object prev = left.execute(variableMap);
        if (!Types.isBoolean(prev))
            throw new ExpressionException(this, "逻辑与表达式{" + this + "}格式正确，左边结果不是布尔型");
        
        if (isDouble && !(Boolean) prev)// && 第一个值为false 结束后面的计算
            return false;// 第一个值为false 结束后面的计算
            
        Object next = right.execute(variableMap);
        if (!Types.isBoolean(next))
            throw new ExpressionException(this, "逻辑与表达式{" + this + "}格式不正常，右边结果不是布尔型");
        
        return (Boolean) prev && (Boolean) next;
    }
    
    @Override
    public String toString()
    {
        StringBuilder strb = new StringBuilder().append(left);
        if (this.isDouble)
            strb.append(" && ");
        else
            strb.append(" & ");
        return strb.append(right).toString();
    }
}
